package com.binguo.service;

import com.binguo.common.exception.ServiceException;
import com.binguo.model.api.vo.CustomerWebLoginVO;
import com.binguo.model.api.vo.EmployeeVO;
import com.binguo.model.api.vo.LoginVO;
import com.binguo.model.model.*;
import com.binguo.model.repository.*;
import com.binguo.thirdPay.MD5Util;
import com.binguo.thirdPay.dashiPay.DaShiPay;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Condition;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.binguo.common.exception.ErrorCode.FIRST_LOGIN;
import static com.binguo.common.exception.ErrorCode.LOGIN_ERROR;
import static com.binguo.common.exception.ErrorCode.PHONE_NOT_EXIST;


/**
 * Created by haibang on 18/5/7.
 */
@Service
public class LoginService {
    @Autowired
    EmployeeRepository employeeRepository;
    @Autowired
    TokenService tokenService;
    @Autowired
    CashierDeskRepository cashierDeskRepository;

    @Autowired
    ProductSurchargeRepository productSurchargeRepository;

    @Autowired
    EmployeeLoginHistoryRepository employeeLoginHistoryRepository;
    @Autowired
    ShopService shopService;
    @Autowired
    DaShiPay daShiPay;
    @Autowired
    CustomerRepository customerRepository;

    public List<EmployeeVO> findEmployees(Integer shopId){
        Shop shop = shopService.findShopById(shopId);
        if (shop.getPayType() == 14){
            daShiPay.dsFaceRegistered();
        }
        Condition condition = new Condition(Employee.class);
        condition.or().andEqualTo("shopid", shopId)
                .andEqualTo("status", 0)
                .andEqualTo("deleted", 0);
       return employeeRepository.findByCondition(condition).stream().map(employee ->
                EmployeeVO.builder()
                .employeeId(employee.getId())
                .account(employee.getAccount())
                .name(employee.getName())
                .empCode(employee.getEmpcode())
                .thumbnail(employee.getThumbnail())
                .phone(employee.getPhone()).build()
        ).collect(Collectors.toList());
    }


    public LoginVO login(String phone, String password, String deviceId, Integer cashierDeskId){
        CashierDesk cashierDesk = cashierDeskRepository.findById(cashierDeskId);
        Integer shopID = cashierDesk.getShopid();
        Condition condition = new Condition(Employee.class);
        condition.or().andEqualTo("phone", phone)
        .andEqualTo("password", password)
        .andEqualTo("shopid",shopID);
       Optional<Employee> employeeOptional = employeeRepository.findByCondition(condition).stream().findFirst();
       if(!employeeOptional.isPresent()) throw new ServiceException(LOGIN_ERROR);
        Employee employee = employeeOptional.get();
        employee.setDeviceid(deviceId);
        employeeRepository.update(employee);
        Shop shop = shopService.findShopById(employee.getShopid());
        //fixme haibang
//       if(employee.getIsfirstlogin() == 0) throw new ServiceException(FIRST_LOGIN);

        this._employeeLoginHistory(employee.getShopid(), employee.getId(), employee.getDeviceid(), cashierDeskId);

       String token = tokenService.createToken(employee.getId().toString(), deviceId).getToken();
       return LoginVO.builder()
               .token(token)
               .employeeId(employee.getId())
               .shopName(shop.getName())
               .status(shop.getStatus())
               .expireTime(shop.getExpiretime().getTime())
               .account(employee.getAccount())
               .name(employee.getName())
               .empCode(employee.getEmpcode())
               .thumbnail(employee.getThumbnail())
               .phone(employee.getPhone())
               .surcharge(_getSurcharge(employee.getShopid()))
               .build();


    }


    private void _employeeLoginHistory(Integer shopId, Integer employeeId, String deviceId, Integer cashierDeskId){
        EmployeeLoginHistory employeeLoginHistory =
                EmployeeLoginHistory.builder()
                        .shopid(shopId)
                        .employeeid(employeeId)
                        .deviceid(deviceId)
                        .deskid(cashierDeskId)
                        .created(new Date())
                        .build();
        employeeLoginHistoryRepository.save(employeeLoginHistory);
    }


    private Long _getSurcharge(Integer shopId){
        Condition condition = new Condition(ProductSurcharge.class);
        condition.or().andEqualTo("shopid", shopId)
        .andEqualTo("deleted", 0);
        return productSurchargeRepository.findByCondition(condition)
                .stream().findFirst().map(ProductSurcharge::getPrice).orElseGet(()-> 0L);


    }


    public void logout(Integer employeeId, String deviceId){
        tokenService.deleteToken(employeeId.toString(), deviceId);
    }

    public void resetPassword(String phone, String newPassword){
        Condition condition = new Condition(Employee.class);
        condition.or().andEqualTo("phone", phone);
        Employee employee = employeeRepository.findBy("phone", phone);
        employee.setPassword(newPassword);
        employee.setIsfirstlogin((byte) 1);
        employeeRepository.update(employee);
    }

    public Shop ypCardLogin(String phone,
                            String password){

        Condition condition = new Condition(Employee.class);
        condition.or().andEqualTo("phone", phone)
                .andEqualTo("password", password);
        Optional<Employee> employeeOptional = employeeRepository.findByCondition(condition).stream().findFirst();
        if(!employeeOptional.isPresent()) {
            throw new ServiceException(LOGIN_ERROR);
        }
        Employee employee = employeeOptional.get();

        Integer shopId = employee.getShopid();

        Shop shop = shopService.findShopById(shopId);

        return shop;
    }

    public CustomerWebLoginVO webCustomerLogin(String phone,
                                               String password){

        CustomerWebLoginVO webLoginVO = new CustomerWebLoginVO();
        Condition condition = new Condition(Customer.class);
        condition.or().andEqualTo("phone",phone);
        List<Customer> customerList = customerRepository.findByCondition(condition);
        if(null == customerList || customerList.size() == 0){
            throw new ServiceException(LOGIN_ERROR);
        }else {
            Customer customer = customerList.get(0);
            if (customer.getPassword() == null){
                customer.setPassword(MD5Util.MD5Lower32("000000"));
                customerRepository.update(customer);
                if (password.equals("000000")){
                    webLoginVO.setCustomerId(customer.getId());
                    webLoginVO.setName(customer.getName());
                }else {
                    throw new ServiceException(LOGIN_ERROR);
                }
            }else {
                password = MD5Util.MD5Lower32(password);
                if (password.equals(customer.getPassword())){
                    webLoginVO.setCustomerId(customer.getId());
                    webLoginVO.setName(customer.getName());
                }else {
                    throw new ServiceException(LOGIN_ERROR);
                }
            }
        }
        return webLoginVO;
    }

    public void webRegisterPassword(Integer customerId,
                                    String newPassword,
                                    String oldPassword){

        Customer customer = customerRepository.findById(customerId);

        String password = customer.getPassword();

        oldPassword = MD5Util.MD5Lower32(oldPassword);

        if (oldPassword.equals(password)){
            customer.setPassword(MD5Util.MD5Lower32(newPassword));
            customerRepository.update(customer);
        }else {
            throw new ServiceException(LOGIN_ERROR);
        }

    }
}
